/* A simple server in the internet domain using TCP
   The port number is passed as an argument */
#include <string>
#include <iostream>
#include <cerrno>
#include <cstring>
#include <cstdlib>
#include <fstream>

#include <sys/types.h> 
#include <sys/socket.h>
#include <netinet/in.h>

//class uid
//{
//private:
//	std::string user;
//	std::string passwd;
//	std::string host_name;
//public:
//	std::string set_user(std::string name){this->user = name;}
//	std::string set_passwd(std::string pass){this->passwd = passwd;}
//	std::string set_host_name(std::string h_name){this->host_name = h_name;}
//
//	std::string get_user(){return this->user;}
//	std::string get_passwd(){return this->passwd;}
//	std::string get_host_name(std::string h_name){this->host_name = h_name;}
//};
//
//void generate()
//{
//	std::fstream fn;
//	fn.open("login_info");
//	uid user_1;
//	uid user_2;
//	user_1.set_user("Andrew");
//	user_1.set_passwd("Andrew");
//
//	user_2.set_user("student");
//	user_2.set_passwd("student");
//	fn << user_1 << user_2;
//}
//
int main(int argc, char *argv[])
{
	std::fstream fn;
	fn.open("login_inf");
        if (argc < 2) {
                std::cerr << "ERROR, no port provided" << std::endl;
                return 1;
        }
        //creates new socket IPv4 TCP and stores descriptor in sockfd
        int sockfd = socket(AF_INET, SOCK_STREAM, 0);
        if (sockfd < 0) {
                std::cerr << "ERROR opening socket" << std::endl;
                return 1;
        }

        //Creates and initializes sock_addr_in structure.
        sockaddr_in serv_addr;
        memset(&serv_addr, 0, sizeof(sockaddr_in));
        serv_addr.sin_family = AF_INET;
        serv_addr.sin_addr.s_addr = INADDR_ANY;
        // htons converts 16bit integer to network byte order.
        int portno = atoi(argv[1]);
        serv_addr.sin_port = htons(portno);

        if(bind(sockfd, (sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) {
                std::cerr << "Can't bind socket: errno " << errno << std::endl;
                return 1;
        }
        // Start listening for incoming connections, 5 is size of backlog queue.
        listen(sockfd, 5);

        sockaddr_in cli_addr;
        socklen_t clilen = sizeof(cli_addr);
	int newsockfd;
	while(newsockfd = accept(sockfd, (sockaddr*)&cli_addr, &clilen))
	{
		if (newsockfd < 0) {
			std::cerr << "ERROR on accept" << std::endl;
			return 1;
		}

		fn << cli_addr.sin_port << std::endl;

		char buffer[256];
		memset(buffer, 0, sizeof(buffer));
		int n = read(newsockfd, buffer, 255);
		if (n < 0) {
			std::cerr << "Error reading from socket" << std::endl;
			return 1;
		}

		int port_n;
		fn >> port_n;
		char* c = (char*)"hi man";
		std::cout << port_n;
		n = write(newsockfd, c, strlen(c));
		if (n < 0) {
			std::cerr << "Error writing to socket" << std::endl;
			return 1;
		}
	fn.close();
	}
        close(newsockfd);
        close(sockfd);
        return 0; 
}
